/**
 *  学习目标：Todos 案例
 */
import React from 'react'
import './styles/base.css'
import './styles/index.css'

export default class App extends React.Component {
  state = {
    // 列表数据
    list: [
      // { id: 1, content: '吃饭', done: true },
      // { id: 2, content: '睡觉', done: false },
      // { id: 3, content: '打豆豆', done: true },
    ],
    // 要显示的类型
    type: 'all',
  }

  // 根据 id 删除数据
  delTodoById = (id) => {
    // console.log('App组件接收到要删除的id', id)
    this.setState({ list: this.state.list.filter((item) => item.id !== id) })
  }

  // 根据 id 更新选中状态
  changeSelectTodoById = (id) => {
    // console.log('App组件接收到的id', id)
    // 🔔注意：React 更新 state 都是通过 setState() 把 新的数据 覆盖 旧的数据
    const newList = this.state.list.map((item) => {
      if (item.id === id) {
        // 需要更新 done
        return {
          ...item,
          done: !item.done,
        }
      } else {
        // 其他的直接返回原数据
        return item
      }
    })
    // console.log(newList)
    this.setState({ list: newList })
  }

  // 删除已完成任务（过滤）
  delDoneTodo = () => {
    this.setState({ list: this.state.list.filter((item) => !item.done) })
  }

  // 更新 type
  changeType = (type) => {
    // console.log('App组件接收到type', type)
    this.setState({ type })
  }

  // 添加任务
  addTodo = (content) => {
    // console.log('App组件接收到content', content)
    this.setState({ list: [{ id: Date.now(), content: content, done: false }, ...this.state.list] })
  }

  // 组件挂载时获取本地存储数据
  componentDidMount() {
    this.setState({
      list: JSON.parse(localStorage.getItem('todos')) || [],
      type: localStorage.getItem('todos-type') || 'all',
    })
  }

  // 当组件(state,props)更新时，设置本地存储数据
  componentDidUpdate() {
    // console.log('组件更新了')
    localStorage.setItem('todos', JSON.stringify(this.state.list))
    localStorage.setItem('todos-type', this.state.type)
  }

  // 全选和取消全选
  changeAllCheck = (checked) => {
    // console.log('App组件接收到checked', checked)
    this.setState({
      list: this.state.list.map((item) => {
        return {
          ...item,
          done: checked,
        }
      }),
    })
  }

  render() {
    return (
      <section className='todoapp'>
        {/* 头部 */}
        <Header addTodo={this.addTodo} />
        {/* 主体 */}
        <Main
          list={this.state.list}
          type={this.state.type}
          delTodoById={this.delTodoById}
          changeSelectTodoById={this.changeSelectTodoById}
          changeAllCheck={this.changeAllCheck}
        />
        {/* 底部 */}
        <Footer
          list={this.state.list}
          type={this.state.type}
          delDoneTodo={this.delDoneTodo}
          changeType={this.changeType}
        />
      </section>
    )
  }
}

class Header extends React.Component {
  state = {
    content: '',
  }

  handleKeyUp = (e) => {
    // console.log(e.key)
    if (e.key === 'Enter') {
      // 非空判断
      if (this.state.content === '') return alert('请输入内容')
      // console.log('你按了回车键')
      this.props.addTodo(this.state.content)
      // 清空输入框
      this.setState({ content: '' })
    } else if (e.key === 'Escape') {
      this.setState({ content: '' })
    }
  }

  handleChange = (e) => {
    console.log(e.target.value)
    // 获取表单数据
    const content = e.target.value.trim()
    // 受控组件更新
    this.setState({ content })
  }

  render() {
    return (
      <header className='header'>
        <h1>todos</h1>
        <input
          onKeyUp={this.handleKeyUp}
          className='new-todo'
          placeholder='What needs to be done?'
          autoFocus
          value={this.state.content}
          onChange={this.handleChange}
        />
      </header>
    )
  }
}

class Main extends React.Component {
  render() {
    const { list, delTodoById, changeSelectTodoById, type } = this.props

    // 计算出用于显示的列表
    let showList = []
    // 根据不同的 type 计算出需要显示的列表数据
    if (type === 'all') {
      // 显示全部
      showList = list
    } else if (type === 'active') {
      // 显示未完成
      showList = list.filter((item) => !item.done)
    } else if (type === 'completed') {
      // 显示已完成
      showList = list.filter((item) => item.done)
    }

    // 计算全选状态
    // .every()  测试一个数组内的所有元素是否都能通过某个指定函数的测试，它返回一个布尔值。
    const checkAll = list.length !== 0 && list.every((item) => item.done)
    // console.log('是否全选', checkAll)

    return (
      <section className='main'>
        {/* <input className='toggle-all' checked type='checkbox' /> */}
        {/* 💥 注意：input 需要指定 id ，点击 label 相当于点了 input */}
        <input
          className='toggle-all'
          checked={checkAll}
          onChange={(e) => this.props.changeAllCheck(e.target.checked)}
          type='checkbox'
          id='toggle-all'
        />
        <label htmlFor='toggle-all'>Mark all as complete</label>
        <ul className='todo-list'>
          {/* 渲染需要显示的列表数据 */}
          {showList.map((item) => (
            <li key={item.id} className={item.done ? 'completed' : ''}>
              <div className='view'>
                <input
                  checked={item.done}
                  onChange={() => changeSelectTodoById(item.id)}
                  className='toggle'
                  type='checkbox'
                />
                <label>{item.content}</label>
                <button onClick={() => delTodoById(item.id)} className='destroy'></button>
              </div>
              <input className='edit' />
            </li>
          ))}
        </ul>
      </section>
    )
  }
}

class Footer extends React.Component {
  // state = {
  //   leftCount: 0,
  // }

  render() {
    const { delDoneTodo, list, changeType, type } = this.props
    return (
      <footer className='footer' style={{ display: list.length === 0 ? 'none' : '' }}>
        <span className='todo-count'>
          {/* 计算剩下的数量 */}
          <strong>{list.filter((v) => !v.done).length}</strong> item left
        </span>
        <ul className='filters'>
          <li>
            <a
              onClick={() => changeType('all')}
              className={type === 'all' ? 'selected' : ''}
              href='#/'
            >
              All
            </a>
          </li>
          <li>
            <a
              onClick={() => changeType('active')}
              className={type === 'active' ? 'selected' : ''}
              href='#/active'
            >
              Active
            </a>
          </li>
          <li>
            <a
              onClick={() => changeType('completed')}
              className={type === 'completed' ? 'selected' : ''}
              href='#/completed'
            >
              Completed
            </a>
          </li>
        </ul>
        <button onClick={() => delDoneTodo()} className='clear-completed'>
          Clear completed
        </button>
      </footer>
    )
  }
}
